package com.bytecodezz.app.status

import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import android.view.WindowManager
import android.widget.LinearLayout
import androidx.annotation.ColorInt
import androidx.core.graphics.ColorUtils
import com.bytecodezz.app.R


/**
 * 1、设置状态栏颜色   setStatusBarColor
 * 2、使指定的View向下Padding偏移一个状态栏高度   setOffsetStatusBar
 *
 */
object StatusBarTools {

    //自定义状态栏对应的id
    private const val STATUS_BAR_TRANSLUCENT_VIEW_ID: Int = R.id.status_bar_view2

    //ViewMargin偏移的tag
    private const val TAG_KEY_HAVE_SET_MARGIN = -123

    //ViewPadding偏移的tag
    private const val TAG_KEY_HAVE_SET_PADDING = -124

    //状态栏颜色
    @ColorInt
    var defaultStatusBarColor = Color.parseColor("#398EFF")
    private var systemUIBarColor = Color.parseColor("#398EFF")

    /******************************* 以下为对外提供的API *************************************/

    /**
     * 设置状态栏颜色
     * @param activity      需要设置的activity
     * @param color         状态栏颜色值 默认取 defaultStatusBarColor
     * @param isImmersion   是否要沉浸风格 默认为false
     */
    fun setStatusBarColor(
        activity: Activity,
        @ColorInt color: Int = defaultStatusBarColor,
        isImmersion: Boolean = false
    ) {
        if (isImmersion) {
            setImmersionBarColor(activity, color)
        } else {
            setNormalBarColor(activity, color)
        }
    }

    /**
     * 使指定的View向下Padding偏移一个状态栏高度，留出状态栏空间，主要用于设置沉浸式后
     *
     * @param activity          需要设置的activity
     * @param targetView        需要偏移的View
     * @param enable            开启或者关闭 默认开启
     * @param isPaddingOrMargin 默认为paddingTop，向下偏移是padding还是margin，true的话是padding，false的话是margin
     */
    fun setOffsetStatusBar(
        activity: Activity,
        targetView: View?,
        enable: Boolean = true,
        isPaddingOrMargin: Boolean = true
    ) {
        if (isPaddingOrMargin) {
            setPaddingStatusBar(activity, targetView, enable)
        } else {
            setMarginStatusBar(activity, targetView, enable)
        }
    }

    /******************************* 以上为对外提供的API *************************************/


    /**
     * 设置状态栏文字颜色主题，亮色或暗色，根据传入的background颜色自动判断
     * 比如 状态栏背景为白色，则自动设置状态栏文字颜色为暗色，如果传入的状态栏背景颜色为黑色，则自动设置状态栏颜色为亮色
     *
     * 注意：单独调用会使得原有flag失效，故该逻辑已嵌套进其他状态中了
     */
    fun setStatusBarText(
        activity: Activity,
        @ColorInt statusBackgroundColor: Int,
        isImmersion: Boolean = false
    ) {
        if (isImmersion) {
            if (isLightColor(statusBackgroundColor)) {
                activity.window.decorView.systemUiVisibility =
                    View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            } else {
                activity.window.decorView.systemUiVisibility =
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            }
        } else {
            // 如果亮色，设置状态栏文字为黑色
            if (isLightColor(statusBackgroundColor)) {
                activity.window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
            } else {
                activity.window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE
            }
        }
    }

    /**
     * 设置普通的状态栏
     * 直接设置颜色即可
     *
     * @param activity 需要设置的activity
     * @param color    状态栏颜色值
     */
    private fun setNormalBarColor(activity: Activity, @ColorInt color: Int) {
        //取消原有的沉浸式状态栏
        cancelImmersionStyle(activity, color)
//        //设置当前颜色下的状态栏文字黑色或者白色
//        setStatusBarText(activity, color)
        //设置状态栏颜色
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //5.0
            activity.window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
            activity.window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
            activity.window.statusBarColor = color
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //4.4
            activity.window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
            val decorView = activity.window.decorView as ViewGroup
            val statusBarView = decorView.findViewById<View>(STATUS_BAR_TRANSLUCENT_VIEW_ID)
            if (statusBarView != null) {
                if (statusBarView.visibility == View.GONE) {
                    statusBarView.visibility = View.VISIBLE
                }
                statusBarView.setBackgroundColor(color)
            } else {
                decorView.addView(
                    createStatusBarView(
                        activity,
                        color
                    )
                )
            }
            configRootView(activity)
        }
    }

    /**
     * 设置沉浸式风格的状态栏
     * 将会隐藏状态栏然后创建自定义的状态栏
     * @param activity activity
     * @param color    状态栏颜色
     */
    private fun setImmersionBarColor(activity: Activity, color: Int) {
        //首先取消系统的状态栏
        showSystemStatusBar(activity, false, color)
        //4.4
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //4.4
            //加入新的状态栏（不加入队列的话会出现页面偏移的Bug）
            Handler(Looper.myLooper()!!).post {
                addStatusBarView(
                    activity,
                    color
                )
            }
        }
    }

    /**
     * 添加自定义状态栏条
     *
     * @param activity 需要设置的 activity
     * @param color    颜色
     */
    private fun addStatusBarView(activity: Activity, @ColorInt color: Int) {
        //获取当前
        val contentView = activity.findViewById<ViewGroup>(android.R.id.content)
        var statusBarView = contentView.findViewById<View>(STATUS_BAR_TRANSLUCENT_VIEW_ID)
        if (statusBarView != null) {
            if (statusBarView.visibility == View.GONE) {
                statusBarView.visibility = View.VISIBLE
            }
            statusBarView.setBackgroundColor(color)
        } else {
            statusBarView = createStatusBarView(activity, color)
            contentView.addView(statusBarView)
        }
    }

    /**
     * 创建自定义的状态栏
     *
     * @param color 状态栏颜色
     * @return View 自己设置好的状态栏
     */
    private fun createStatusBarView(activity: Activity, color: Int): View {
        // 创建一个和系统状态栏一样高的View
        val statusBarView = View(activity)
        val params = LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            getStatusBarHeight(activity)
        )
        statusBarView.layoutParams = params
        statusBarView.setBackgroundColor(color)
        statusBarView.id = STATUS_BAR_TRANSLUCENT_VIEW_ID
        return statusBarView
    }

    /**
     * 显示或者隐藏系统状态栏
     * 通过设置FLAG将系统状态栏显示或者隐藏
     * API>30 (R) 可使用 WindowInsetsController 进行管理
     */
    @Suppress("DEPRECATION")
    private fun showSystemStatusBar(activity: Activity, isShowSystemUI: Boolean, color: Int) {
        if (isShowSystemUI) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //5.0
                activity.window.statusBarColor = systemUIBarColor
                // 如果亮色，设置状态栏文字为黑色
                if (isLightColor(color)) {
                    activity.window.decorView.systemUiVisibility =
                        View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
                } else {
                    activity.window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE
                }
//                activity.window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE

            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //4.4
                activity.window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
            }
        } else {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //5.0
                systemUIBarColor = activity.window.statusBarColor
                activity.window.statusBarColor = Color.TRANSPARENT
                if (isLightColor(color)) {
                    activity.window.decorView.systemUiVisibility =
                        View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                } else {
                    activity.window.decorView.systemUiVisibility =
                        View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                }
//                setStatusBarText(activity, color)
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //4.4
                activity.window.setFlags(
                    WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
                    WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                )
            }
        }
    }

    /**
     * 设置根布局参数
     *
     * @param activity 需要设置的 activity
     */
    private fun configRootView(activity: Activity) {
        val parent = activity.findViewById<ViewGroup>(android.R.id.content)
        var i = 0
        val count = parent.childCount
        while (i < count) {
            val childView = parent.getChildAt(i)
            if (childView is ViewGroup) {
                childView.setFitsSystemWindows(true)
                childView.clipToPadding = true
            }
            i++
        }
    }

    /**
     * 取消沉浸式风格的状态栏
     *
     * @param activity activity
     * @param color 当前要设置的状态栏背景色，根据该颜色配置对应的状态栏文字颜色
     */
    private fun cancelImmersionStyle(activity: Activity, color: Int) {
        //显示原来的状态栏
        showSystemStatusBar(activity, true, color)
        //隐藏自定义的状态
        val decorView = activity.window.decorView as ViewGroup
        val contentView = activity.findViewById<ViewGroup>(android.R.id.content)
        val statusBarView = contentView.findViewById<View>(STATUS_BAR_TRANSLUCENT_VIEW_ID)
        if (statusBarView != null) {
            if (statusBarView.visibility == View.VISIBLE) {
                statusBarView.visibility = View.GONE
            }
            decorView.removeView(statusBarView)
        }
    }


    /**
     * 使指定的View向下Padding偏移一个状态栏高度，留出状态栏空间，主要用于设置沉浸式后,页面顶到顶端有突兀感
     *
     * @param activity      需要设置的activity
     * @param targetView    需要偏移的View
     * @param enable        开启或者关闭
     */
    private fun setPaddingStatusBar(activity: Activity, targetView: View?, enable: Boolean) {
        if (targetView != null) {
            val haveSetOffset = targetView.getTag(TAG_KEY_HAVE_SET_PADDING)
            val paddingTop = if (enable) {
                if (haveSetOffset != null && haveSetOffset as Boolean) {
                    return
                }
                targetView.paddingTop + getStatusBarHeight(activity)
            } else {
                if (haveSetOffset != null && haveSetOffset as? Boolean == null) {
                    return
                }
                targetView.paddingTop - getStatusBarHeight(activity)
            }
            targetView.setPadding(
                targetView.paddingLeft,
                paddingTop,
                targetView.paddingRight,
                targetView.paddingBottom
            )
            targetView.setTag(TAG_KEY_HAVE_SET_PADDING, enable)
        }
    }

    /**
     * 使指定的View向下Margin偏移一个状态栏高度，留出状态栏空间，主要用于设置沉浸式后,页面顶到顶端有突兀感
     *
     * @param activity       需要设置的activity
     * @param needOffsetView 需要偏移的View
     */
    private fun setMarginStatusBar(activity: Activity, needOffsetView: View?, enable: Boolean) {
        if (needOffsetView != null) {
            val haveSetOffset = needOffsetView.getTag(TAG_KEY_HAVE_SET_MARGIN)
            val layoutParams = needOffsetView.layoutParams as MarginLayoutParams
            val marginTop = if (enable) {
                if (haveSetOffset != null && haveSetOffset as Boolean) {
                    return
                }
                layoutParams.topMargin + getStatusBarHeight(activity)
            } else {
                if (haveSetOffset != null && haveSetOffset as? Boolean == null) {
                    return
                }
                layoutParams.topMargin - getStatusBarHeight(activity)
            }
            layoutParams.setMargins(
                layoutParams.leftMargin,
                marginTop,
                layoutParams.rightMargin,
                layoutParams.bottomMargin
            )
            needOffsetView.layoutParams = layoutParams
            needOffsetView.setTag(TAG_KEY_HAVE_SET_MARGIN, enable)
        }
    }


    /**
     * 判断颜色是不是亮色
     *
     * @param color
     * @return
     * @from https://stackoverflow.com/questions/24260853/check-if-color-is-dark-or-light-in-android
     */
    private fun isLightColor(@ColorInt color: Int): Boolean {
        return ColorUtils.calculateLuminance(color) >= 0.5
    }

    /**
     * 获取状态栏高度
     *
     * @param context context
     * @return 状态栏高度
     */
    private fun getStatusBarHeight(context: Context): Int {
        // 获得状态栏高度
        val resourceId = context.resources.getIdentifier("status_bar_height", "dimen", "android")
        return context.resources.getDimensionPixelSize(resourceId)
    }

}

